package database

import (
	"app/config"
	"app/pkg/log"
	"fmt"
	"go.uber.org/zap"
	"sync"
	"time"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"gorm.io/gorm/schema"
)

var (
	instances = make(map[string]*gorm.DB)
	mu        sync.Mutex
)

func Default() *gorm.DB {
	return Get("default")
}

func Get(group string) (db *gorm.DB) {
	db, err := GetInstance(group)
	if err != nil {
		panic(err)
	}
	return db
}

func GetInstance(group string) (instance *gorm.DB, err error) {
	mu.Lock()
	defer mu.Unlock()
	var ok bool
	if instance, ok = instances[group]; ok {
		return instance, nil
	}
	var cfg *config.DatabaseConfig
	if cfg, ok = config.Config.Database[group]; !ok {
		return nil, fmt.Errorf("未找到数据库组配置: %s", group)
	}
	var dialector gorm.Dialector
	switch cfg.Type {
	case "mysql":
		dialector = mysql.Open(cfg.Dsn)
	case "postgres":
	case "sqlite":
	case "clickhouse":
	default:
		return nil, fmt.Errorf("不支持的数据库类型：%s", cfg.Type)
	}
	db, err := gorm.Open(dialector, getConfig(cfg))
	if err != nil {
		return nil, err
	}
	sqlDB, err := db.DB()
	if err != nil {
		return nil, err
	}
	sqlDB.SetMaxIdleConns(cfg.MaxIdleConns)
	sqlDB.SetMaxOpenConns(cfg.MaxOpenConns)
	sqlDB.SetConnMaxLifetime(cfg.MaxLifetime)

	instances[group] = db
	return db, nil

}

// getConfig 获取gorm的配置信息
func getConfig(c *config.DatabaseConfig) *gorm.Config {
	return &gorm.Config{
		Logger: NewGormLogger(
			Writer{log.Logger("database").Logger()},
			logger.Config{
				SlowThreshold: time.Second, // 慢 SQL 阈值
				LogLevel:      logger.Info, // 日志级别
			},
		),
		NamingStrategy: schema.NamingStrategy{
			TablePrefix: c.Prefix, // 表名前缀
			// SingularTable: true,  // 使用单数表名
		},
	}
}

type Writer struct {
	Logger *zap.SugaredLogger
}

func (w Writer) Printf(format string, args ...interface{}) {
	w.Logger.Infof(format, args...)
}
